﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BigPang.Common.Service;
using System.ServiceModel;
using System.Threading;
using BigPang.Server.GamePlay.Objects;
using System.Threading.Tasks;
using BigPang.Common.GamePlay;
using BigPang.Common.GamePlay.Objects;

namespace BigPang.Server.GamePlay
{
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, ConcurrencyMode=ConcurrencyMode.Multiple, AutomaticSessionShutdown=true)]
    public class GameSession : IGameService, IDisposable
    {
        public static Dictionary<string, OperationContext> mSessionListener = new Dictionary<string, OperationContext>();

        public static List<GameSession> Sessions { get; private set; }

        int mObjId;

        static GameSession()
        {
            Sessions = new List<GameSession>();
        }

        #region IGameService 成员

        public GameSession()
        {
            Sessions.Add(this);
        }

        public static async void RiseEvent( Action<IGameCallback> work )
        {
            await TaskEx.Run(() =>
            {
                Parallel.ForEach(mSessionListener, (ocPair) => { work(ocPair.Value.GetCallbackChannel<IGameCallback>()); });
            });
        }

        public void Join( string name, out string playerId )
        {
            Console.WriteLine("player loged in ...");

            playerId = OperationContext.Current.SessionId;

            mSessionListener[playerId] = OperationContext.Current;

            OperationContext.Current.Channel.Closing += new EventHandler(Channel_Closing);
            OperationContext.Current.Channel.Closed += new EventHandler(Channel_Closed);
            OperationContext.Current.Channel.Faulted += new EventHandler(Channel_Faulted);
            OperationContext.Current.InstanceContext.Closed += new EventHandler(InstanceContext_Closed);

            IGameCallback callback = OperationContext.Current.GetCallbackChannel<IGameCallback>();

            List<GameObject> list = GameManager.GetList();

            foreach (GameObject obj in list)
            {
                callback.OnObjectCreated(typeof(Tank).ToString(), obj.Name, obj.Id, obj.X, obj.Y);
            }

            STank tank = new STank();
            tank.Name = name;
            tank.Register();

            mObjId = tank.Id;

            callback.TakeControl(mObjId);
        }

        void InstanceContext_Closed(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }

        void Channel_Faulted(object sender, EventArgs e)
        {
            IContextChannel m = sender as IContextChannel;
            string id = m.SessionId;

            GameSession gs = mSessionListener[id].Channel.GetProperty<GameSession>();
        }

        void Channel_Closed(object sender, EventArgs e)
        {
            IContextChannel m = sender as IContextChannel;
            string id = m.SessionId;

            GameSession gs = mSessionListener[id].Channel.GetProperty<GameSession>();
        }

        void Channel_Closing(object sender, EventArgs e)
        {
            IContextChannel m = sender as IContextChannel;
            string id = m.SessionId;

            GameSession gs = mSessionListener[id].Channel.GetProperty<GameSession>();
        }



        public void Quit()
        {
            mSessionListener.Remove(OperationContext.Current.SessionId);

            
        }

        #endregion

        #region IGameService 成员


        public void StartMove(int x, int y, int direction, float speed)
        {
            GameSession.RiseEvent((IGameCallback callback) => { callback.OnPlayerStartMove(mObjId, x, y, direction); });

            Console.WriteLine(mObjId + " x: " + x + " y: " + y);
        }

        public void StopMove(int x, int y)
        {
            GameObject obj = GameManager.Get(mObjId);

            obj.X = x;
            obj.Y = y;
            
            GameSession.RiseEvent((IGameCallback callback) => { callback.OnPlayerStopMove(mObjId, x, y); });
        }

        #endregion

        #region IGameService 成员


        public void Action(int actionId)
        {
            GameSession.RiseEvent((IGameCallback callback) => { callback.OnAction(mObjId, actionId); });
        }

        #endregion

        #region IGameService 成员


        public void Hit(int id, int sourceId)
        {
            GameSession.RiseEvent((IGameCallback callback) => { callback.OnHit(id, sourceId); });
        }

        #endregion

        #region IDisposable 成员

        public void Dispose()
        {
            Console.WriteLine("player quit");
        }

        #endregion
    }
}
